package com.lsh.oms.core.service.order;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lsh.base.common.json.JsonUtils;
import com.lsh.base.common.model.CommonResult;
import com.lsh.oms.api.model.es.OrderHeadForEs;
import com.lsh.oms.api.model.order.returnro.ReturnDetailConfirmDto;
import com.lsh.oms.api.model.order.returnro.ReturnDetailDto;
import com.lsh.oms.api.model.order.returnro.ReturnHeadConfirmDto;
import com.lsh.oms.api.model.order.returnro.ReturnHeadDto;
import com.lsh.oms.api.model.status.UpdateStatusDto;
import com.lsh.oms.core.constant.ReturnCode;
import com.lsh.oms.core.enums.*;
import com.lsh.oms.core.exception.BusinessException;
import com.lsh.oms.core.model.order.*;
import com.lsh.oms.core.model.po.OmsTask;
import com.lsh.oms.core.proxy.service.EsProxy;
import com.lsh.oms.core.redis.RedisTemplate;
import com.lsh.oms.core.service.asynservice.OmsEventBus;
import com.lsh.oms.core.service.other.RoOrderService;
import com.lsh.oms.core.service.other.ShippingOrderService;
import com.lsh.oms.core.service.other.SignOrderService;
import com.lsh.oms.core.service.po.OmsTaskService;
import com.lsh.oms.core.utils.IdGenerator;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 订单发货service
 */
@Service
@Deprecated
public class OrderReturnService extends AbstractOrderService {

    private static Logger logger = LoggerFactory.getLogger(OrderReturnService.class);

    @Autowired
    private RoOrderService roOrderService;

    @Autowired
    private ShippingOrderService shippingService;

    @Autowired
    private OrderReceiptService orderReceiptService;

    @Autowired
    private OmsTaskService omsTaskService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 创建返仓单
     *
     * @param returnHeadDto 返仓数据
     * @param orderHead     订单信息
     * @param logSign       唯一标识
     * @return 返仓结果
     */
    public CommonResult<Object> createRO(ReturnHeadDto returnHeadDto, OrderHead orderHead, String logSign) {
        OrderShippingHead shippingOrder = shippingService.selectOneByOrderCode(orderHead.getOrderCode(), false);
        if (shippingOrder == null) {
            throw new BusinessException(ReturnCode.FIND_ORDER_IS_NULL, "用户订单号未查询到发货单");
        }

        CommonResult<Object> commonResult;

        if (returnHeadDto.getConfirmFlag() == null) {
            returnHeadDto.setConfirmFlag(0);
        }

        JSONObject extJson = JSON.parseObject(orderHead.getExt());
        String orderDc = extJson.getString("orderDc");

        if (returnHeadDto.getDetails() == null || returnHeadDto.getDetails().isEmpty()) {
            // 全单返仓处理  包括 现场返仓 和 售后返仓
            commonResult = this.createRO4Full(returnHeadDto, orderHead, logSign);
        } else {
            // 部分返仓处理  目前只有 售后返仓
            commonResult = this.createRO4Part(returnHeadDto, orderHead, logSign);
        }

        if (commonResult.getCode().equals(ReturnCode.REQUEST_SUCCESS)) {
            this.refundEvent(returnHeadDto.getOrderCode(), returnHeadDto.getReturnOrderType());
            this.addMisTask((OrderRoHead) commonResult.getData());
            if (returnHeadDto.getConfirmFlag() == 0 && !shippingOrder.goWithoutTms()) {
                //添加提交ofc任务
                this.addOfcTask((OrderRoHead) commonResult.getData());
            }
        }

        return commonResult;
    }

    /**
     * 发起退款事务 // 添加生成退款单任务
     *
     * @param orderCode
     * @param returnOrderType
     */
    private void refundEvent(Long orderCode, Integer returnOrderType) {
        if (returnOrderType.equals(OrderRoType.SPOT_RECEIPT.getValue())) {

            UpdateStatusDto dto = new UpdateStatusDto();
            dto.setOrderNo(orderCode);
            OmsEventBus.post(dto);
        }
    }


    /**
     * 全单返仓
     *
     * @param orderHead 订单信息
     * @param logSign   唯一标识
     * @return
     * @throws Exception 异常信息
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public CommonResult<Object> createRO4Full(ReturnHeadDto returnHeadDto, OrderHead orderHead, String logSign) {

        OrderShippingHeadWithBLOBs orderShippingHeadWithBLOBs = shippingService.getBolbs(orderHead.getOrderCode());
        if (orderShippingHeadWithBLOBs == null) {
            throw new BusinessException(ReturnCode.REQUEST_FAIL, "此订单未生成发货单");
        }

        List<OrderRoHead> orderRoHeadsFormDb = roOrderService.getRoHeadList(orderHead.getOrderCode());

        // (wms)现场返仓只能又一次,多点业务售后返仓只能又一次，所以 现场返仓 ，售后返仓 都只能有一个
//        if (orderRoHeadsFormDb != null && returnHeadDto.getReturnOrderType().equals(OrderRoType.SPOT_RECEIPT.getValue())) {
        if (orderRoHeadsFormDb != null) {

            for (OrderRoHead orderRoHead : orderRoHeadsFormDb) {
                if((orderRoHead.getReturnOrderType().compareTo(returnHeadDto.getReturnOrderType())) == 0){
                    throw new BusinessException(ReturnCode.REQUEST_SUCCESS, "此订单已经生成返仓.请查询");
                }
            }
        }

        // TODO
        if (!redisTemplate.lock("oms:ro:" + orderHead.getOrderCode().toString(), "ro", 5L)) {
            throw new BusinessException(ReturnCode.FIND_ORDER_IS_NULL, "操作太频繁,请稍后再试");
        }

        if (returnHeadDto.getReturnOrderType().equals(OrderRoType.SPOT_RECEIPT.getValue())) {
            OrderSignHead orderSignHead = signOrderService.getSignHeadByOrderId(orderHead.getOrderCode(),false);
            if (orderSignHead != null) {

                this.disableOrderSignAndEs(orderSignHead, logSign);
            }
        }

        OrderRoHead orderRoHead = this.createOrderRoHead(orderShippingHeadWithBLOBs, orderHead);
        // 添加返仓类型 参数必传
        orderRoHead.setReturnOrderType(returnHeadDto.getReturnOrderType());

//        String deliveryInfo = returnHeadDto.getDeliveryInfo();
//
//        if (StringUtils.isNotBlank(deliveryInfo)) {
//            JSONObject deliveryInfoJson = JSON.parseObject(deliveryInfo);
//            if (deliveryInfoJson != null) {
//                String extStr = orderRoHead.getExt();
//                if (StringUtils.isBlank(extStr)) {
//                    extStr = "{}";
//                }
//                JSONObject roExt = JSON.parseObject(extStr);
//                if (roExt == null) {
//                    roExt = new JSONObject();
//                }
//
//                roExt.put("deliveryInfo", deliveryInfoJson.toJSONString());
//
//                orderRoHead.setExt(roExt.toJSONString());
//            }
//        }

        if (StringUtils.isNotBlank(returnHeadDto.getAsfId())) {
            JSONObject extJsonObject = JSON.parseObject(orderRoHead.getExt());
            extJsonObject.put("asf_id", returnHeadDto.getAsfId());
            extJsonObject.put("supplier_group_id",orderHead.getSupplierGroupId());
            orderRoHead.setExt(extJsonObject.toJSONString());
        }

        List<OrderRoDetail> orderRoDetailList = this.createOrderRoDetails(orderShippingHeadWithBLOBs, orderRoHead);

        orderRoHead.setDetails(orderRoDetailList);

        Boolean flag = roOrderService.createRo4Saas(orderRoHead, true, true);

        CommonResult<Object> res = new CommonResult<>();
        if (orderRoHead != null) {

            this.notifyEs(orderRoHead, true, logSign);
            res.setCode(ReturnCode.REQUEST_SUCCESS);
            res.setData(orderRoHead);
        } else {
            res.setCode(ReturnCode.REQUEST_FAIL);
        }

        return res;
    }

    /**
     * 确认返仓数据 定损
     *
     * @param headConfirmDto
     * @param logSign
     * @return
     */
    @Transactional
    public CommonResult<Object> confirmRO(ReturnHeadConfirmDto headConfirmDto, String logSign) {

        List<OrderRoHead> orderRoHeads = roOrderService.getOrderRoHead(headConfirmDto.getOrderCode(), ReturnStatus.Waiting_Confirm_So.getIndex(), true);
        if (orderRoHeads == null || orderRoHeads.isEmpty() || orderRoHeads.size() > 1) {
            throw new BusinessException(ReturnCode.FIND_ORDER_IS_NULL, headConfirmDto.getOrderCode() + "待确认返仓单有误");
        }
        //需要确认的返仓单
        OrderRoHead orderRoHead = orderRoHeads.get(0);

        //确认数据汇总
        Map<Long, BigDecimal> skuRealQtyMap = new HashMap<>();
        for (ReturnDetailConfirmDto returnDto : headConfirmDto.getDetails()) {

            BigDecimal dtoSkuQty = skuRealQtyMap.get(returnDto.getSkuId());
            if (dtoSkuQty == null) {
                skuRealQtyMap.put(returnDto.getSkuId(), returnDto.getRealQty());
            } else {
                skuRealQtyMap.put(returnDto.getSkuId(), returnDto.getRealQty().add(dtoSkuQty));
            }
        }

        // 链商承担返仓确认详情列表
        List<OrderRoDetail> lshRoDetails = new ArrayList<>();
        // 司机承担返仓确认详情列表
        List<OrderRoDetail> driverRoDetails = new ArrayList<>();
        List<OrderRoDetail> orderRoDetailList = orderRoHead.getDetails();
        // 价格排序  司机承担价格
        Collections.sort(orderRoDetailList);
        for (OrderRoDetail fromDbRoDetail : orderRoDetailList) {

            BigDecimal confirmSkuQty = skuRealQtyMap.get(fromDbRoDetail.getSkuId());

            if (confirmSkuQty == null) {
                throw new BusinessException(ReturnCode.FIND_ORDER_IS_NULL, fromDbRoDetail.getSkuId() + ":无确认数量");
            }

            //确认数量大于返仓数量
            if (fromDbRoDetail.getRealQty().compareTo(confirmSkuQty) < 0) {

                lshRoDetails.add(fromDbRoDetail);
                skuRealQtyMap.put(fromDbRoDetail.getSkuId(), confirmSkuQty.subtract(fromDbRoDetail.getRealQty()));

            } else if (fromDbRoDetail.getRealQty().compareTo(confirmSkuQty) == 0) {

                lshRoDetails.add(fromDbRoDetail);

                skuRealQtyMap.put(fromDbRoDetail.getSkuId(), BigDecimal.ZERO);
            } else {

                OrderRoDetail driverRoDetail = new OrderRoDetail();
                BeanUtils.copyProperties(fromDbRoDetail, driverRoDetail);
                // TODO 顺序
                driverRoDetail.setRealQty(fromDbRoDetail.getRealQty().subtract(confirmSkuQty));
                if (confirmSkuQty.compareTo(BigDecimal.ZERO) > 0) {
                    fromDbRoDetail.setRealQty(confirmSkuQty);
                    lshRoDetails.add(fromDbRoDetail);
                }

                driverRoDetails.add(driverRoDetail);

                skuRealQtyMap.put(fromDbRoDetail.getSkuId(), BigDecimal.ZERO);
            }
        }
        int successFlag;
        if (driverRoDetails.isEmpty()) {//确认等于返仓
            //修改原返仓单状态待提交SO
            OrderRoHead update = new OrderRoHead();
            update.setReturnOrderId(orderRoHead.getReturnOrderId());
            update.setStatus(ReturnStatus.Waiting_Submit_So.getIndex());
            successFlag = this.roOrderService.updateByReturnOrderId(update);
            this.notifyEs(update);
//            this.addTask(orderRoHead);
            this.addOfcTask(orderRoHead);
            this.refundEvent(orderRoHead.getOrderId(), orderRoHead.getReturnOrderType());
        } else {
            //修改原返仓单状态
            OrderRoHead update = new OrderRoHead();
            update.setReturnOrderId(orderRoHead.getReturnOrderId());
            update.setStatus(ReturnStatus.Return_Success.getIndex());
            this.roOrderService.updateByReturnOrderId(update);
//            this.addMisTask(orderRoHead);
            this.notifyEs(update);
            //生成待提交SO 返仓单
            if (!CollectionUtils.isEmpty(lshRoDetails)) {
                OrderRoHead lshRoHeadInsert = this.builderOrderRoHead(orderRoHead, lshRoDetails);
                lshRoHeadInsert.setType(RoDutyType.DUTY_LSH.getIndex());
                lshRoHeadInsert.setIsMp(IsMp.SUBMIT_SO.getCode());
                lshRoHeadInsert.setStatus(ReturnStatus.Waiting_Submit_So.getIndex());
                this.addOfcTask(lshRoHeadInsert);
                this.refundEvent(lshRoHeadInsert.getOrderId(), lshRoHeadInsert.getReturnOrderType());

                roOrderService.createRo4Cloud(lshRoHeadInsert);
                this.notifyEs(lshRoHeadInsert, false, logSign);
            }

            //生成司机承担 返仓状态已完成 返仓单
            OrderRoHead driverRoHeadInsert = this.builderOrderRoHead(orderRoHead, driverRoDetails);
            driverRoHeadInsert.setType(RoDutyType.DUTY_DRIVER.getIndex());
            driverRoHeadInsert.setIsMp(IsMp.NO_SUBMIT_SO.getCode());
            driverRoHeadInsert.setStatus(ReturnStatus.Return_Success.getIndex());

            successFlag = roOrderService.createRo4Cloud(driverRoHeadInsert);
            this.notifyEs(driverRoHeadInsert, false, logSign);
        }

        CommonResult<Object> res = new CommonResult<>();
        if (successFlag > 0) {

            res.setCode(ReturnCode.REQUEST_SUCCESS);
            res.setData(successFlag > 0);
        } else {

            res.setCode(ReturnCode.REQUEST_FAIL);
        }

        return res;
    }

    public static void main(String[] args) {
        List<OrderRoDetail> orderRoDetailList = new ArrayList<>();
        OrderRoDetail or1 = new OrderRoDetail();
        or1.setSkuId(2002005L);
        or1.setPrice(new BigDecimal("13.87"));

        OrderRoDetail or2 = new OrderRoDetail();
        or2.setSkuId(1002035L);
        or2.setPrice(new BigDecimal("14.55"));

        OrderRoDetail or3 = new OrderRoDetail();
        or3.setSkuId(4002405L);
        or3.setPrice(new BigDecimal("43.00"));

        OrderRoDetail or4 = new OrderRoDetail();
        or4.setSkuId(1002035L);
        or4.setPrice(new BigDecimal("34.54"));

        orderRoDetailList.add(or1);
        orderRoDetailList.add(or2);
        orderRoDetailList.add(or3);
        orderRoDetailList.add(or4);

        Collections.sort(orderRoDetailList);

        for (OrderRoDetail or : orderRoDetailList) {

            System.out.println(JSON.toJSONString(or));
        }
    }

    /**
     * @param soureRoHead
     * @param targetRodetails
     * @return
     */
    private OrderRoHead builderOrderRoHead(OrderRoHead soureRoHead, List<OrderRoDetail> targetRodetails) {
        OrderRoHead targetRohead = new OrderRoHead();

        BeanUtils.copyProperties(soureRoHead, targetRohead);

        targetRohead.setId(null);
        targetRohead.setReturnOrderId(IdGenerator.genId());
        targetRohead.setFOrderId(soureRoHead.getReturnOrderId());

        BigDecimal totalQty = BigDecimal.ZERO;
        BigDecimal totalRealQty = BigDecimal.ZERO;
        BigDecimal totalMoney = BigDecimal.ZERO;
        for (OrderRoDetail targetRoDetail : targetRodetails) {

            BigDecimal realQty = targetRoDetail.getRealQty();
            BigDecimal saleUnit = targetRoDetail.getSaleUnit();
            BigDecimal price = targetRoDetail.getPrice();

            if (saleUnit == null || saleUnit.compareTo(BigDecimal.ONE) < 0) {
                throw new BusinessException(ReturnCode.FIND_ORDER_IS_NULL, targetRoDetail.getSkuId() + ":销售箱规错误");
            }

            BigDecimal qty = realQty.divide(saleUnit).setScale(4, BigDecimal.ROUND_HALF_UP);
            BigDecimal money = qty.multiply(price);

            targetRoDetail.setMoney(money);
            targetRoDetail.setQty(qty);
            targetRoDetail.setReturnOrderId(targetRohead.getReturnOrderId());
            totalQty = totalQty.add(qty);
            totalRealQty = totalRealQty.add(realQty);
            totalMoney = totalMoney.add(money);
        }

        targetRohead.setMoney(totalMoney);
        targetRohead.setSkuCount(totalQty);
        targetRohead.setRealSkuCount(totalRealQty);
        targetRohead.setDetails(targetRodetails);

        return targetRohead;
    }


    /**
     * 添加后续处理任务
     *
     * @param orderRoHead 订单号
     */
//    private void addTask(OrderRoHead orderRoHead) {
//
//        OmsTask omsTask4ofc = new OmsTask();
//
//        omsTask4ofc.setTaskType(TaskType.PUSH_RO.getCode());
//        omsTask4ofc.setTaskStatus(TaskStatus.TASK_UN_DEAL.getCode());
//        omsTask4ofc.setRefCode(String.valueOf(orderRoHead.getReturnOrderId()));
//        omsTask4ofc.setContent(String.valueOf(orderRoHead.getReturnOrderId()));
//
//        omsTaskService.add(omsTask4ofc);
//
//        if (orderRoHead.getReturnOrderType().equals(OrderRoType.AFTER_RECEIPT.getValue())) {
//
//            OmsTask omsTask4mis = new OmsTask();
//            omsTask4mis.setTaskType(TaskType.PUSH_MIS.getCode());
//            omsTask4mis.setTaskStatus(TaskStatus.TASK_UN_DEAL.getCode());
//            omsTask4mis.setRefCode(String.valueOf(orderRoHead.getReturnOrderId()));
//            JSONObject extJsonObject = JSON.parseObject(orderRoHead.getExt());
//            String asfId = extJsonObject.getString("asf_id");
//            omsTask4mis.setContent(asfId);
//
//            omsTaskService.add(omsTask4mis);
//        }
//    }

    /**
     * 通知mis
     *
     * @param orderRoHead
     */
    private void addMisTask(OrderRoHead orderRoHead) {

        if (orderRoHead.getReturnOrderType().equals(OrderRoType.AFTER_RECEIPT.getValue())) {

            OmsTask omsTask4mis = new OmsTask();
            omsTask4mis.setTaskType(TaskType.PUSH_MIS.getCode());
            omsTask4mis.setTaskStatus(TaskStatus.TASK_UN_DEAL.getCode());
            omsTask4mis.setRefCode(String.valueOf(orderRoHead.getReturnOrderId()));
            JSONObject extJsonObject = JSON.parseObject(orderRoHead.getExt());
            String asfId = extJsonObject.getString("asf_id");
            omsTask4mis.setContent(asfId);
            omsTask4mis.setVenderId(orderRoHead.getVenderId());

            omsTaskService.add(omsTask4mis);
        }
    }


    /**
     * 提交ofc
     *
     * @param orderRoHead 订单号
     */
    private void addOfcTask(OrderRoHead orderRoHead) {

        OmsTask omsTask4ofc = new OmsTask();

        omsTask4ofc.setTaskType(TaskType.PUSH_RO.getCode());
        omsTask4ofc.setTaskStatus(TaskStatus.TASK_UN_DEAL.getCode());
        omsTask4ofc.setRefCode(String.valueOf(orderRoHead.getReturnOrderId()));
        omsTask4ofc.setContent(String.valueOf(orderRoHead.getReturnOrderId()));

        omsTaskService.add(omsTask4ofc);
    }

    /**
     * 创建部分返仓单
     *
     * @param orderHead 订单头信息
     * @param logSign   唯一标记
     * @return 返回值
     * @throws Exception 异常信息
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public CommonResult<Object> createRO4Part(ReturnHeadDto returnHeadDto, OrderHead orderHead, String logSign) {

        CommonResult<Object> res = new CommonResult<>();
        Long orderCode = orderHead.getOrderCode();
        List<OrderRoHead> orderRoHeadsFormDb = roOrderService.getRoHeadList(orderHead.getOrderCode());
        // (wms)现场返仓只能又一次,多点业务售后返仓只能又一次，所以 现场返仓 ，售后返仓 都只能有一个
        if (orderRoHeadsFormDb != null) {
            for (OrderRoHead orderRoHead : orderRoHeadsFormDb) {
                if((orderRoHead.getReturnOrderType().compareTo(returnHeadDto.getReturnOrderType())) == 0){
                    throw new BusinessException(ReturnCode.REQUEST_SUCCESS, "此订单已经生成返仓.请查询");
                }
            }
        }

        OrderShippingHeadWithBLOBs oshs = shippingService.getBolbs(orderCode);
        if (oshs == null) {
            throw new BusinessException(ReturnCode.REQUEST_FAIL, "此订单未生成发货单");
        }

        // TODO
        if (!redisTemplate.lock("oms:ro:" + orderHead.getOrderCode().toString(), "ro", 5L)) {
            throw new BusinessException(ReturnCode.FIND_ORDER_IS_NULL, "操作太频繁,请稍后再试");
        }

        if (returnHeadDto.getReturnOrderType().equals(OrderRoType.SPOT_RECEIPT.getValue())) {
            OrderSignHead orderSignHead = signOrderService.getSignHeadByOrderId(orderHead.getOrderCode(),false);
            if (orderSignHead != null) {
                this.disableOrderSignAndEs(orderSignHead, logSign);
            }
        }

        List<OrderShippingDetail> shippingDetails = shippingService.getDetails(oshs.getShippingOrderId());
        Map<String, ReceiptItem> codeItemMap = new HashMap<>();
        for (OrderShippingDetail shippingDetail : shippingDetails) {
            ReceiptItem receiptItem = new ReceiptItem(shippingDetail.getItemId(), shippingDetail.getSupplierOrg());

            String detailKey = shippingDetail.getCode() + ":" + shippingDetail.getSkuId();
            codeItemMap.put(detailKey, receiptItem);
        }

        Map<Long, BigDecimal> orderReceiptItem = new HashMap<>();
        for (ReturnDetailDto returnDetail : returnHeadDto.getDetails()) {
            BigDecimal realQty = returnDetail.getRealQty();
            BigDecimal saleUnit = returnDetail.getSaleUnit();
            BigDecimal returnQty;
            if (realQty != null && saleUnit != null && saleUnit.compareTo(BigDecimal.ZERO) > 0) {
                returnQty = realQty.divide(saleUnit, 4, BigDecimal.ROUND_HALF_DOWN);
            } else {
                throw new BusinessException(ReturnCode.REQUEST_FAIL, "请求返仓数据有误");
            }

            BigDecimal qty = orderReceiptItem.get(returnDetail.getSkuId());

            if (qty == null || qty.compareTo(BigDecimal.ZERO) == 0) {
                orderReceiptItem.put(returnDetail.getSkuId(), returnQty);
            } else {
                orderReceiptItem.put(returnDetail.getSkuId(), returnQty.add(qty));
            }
        }

        JSONObject content = this.orderReturn(orderReceiptItem, oshs, shippingDetails, logSign);
        String returnStr = content.getString("return");
        String receiptStr = content.getString("receipt");
        JSONObject returnOrder = null;
        CalOrderReceiptContent receiptContent = null;
        if (StringUtils.isNotBlank(returnStr) && returnStr.length() > 5) {
            returnOrder = content.getJSONObject("return");
            logger.info(orderCode + "-returnOrder-" + returnOrder.toJSONString());
        }

        if (StringUtils.isNotBlank(receiptStr) && receiptStr.length() > 5) {
            receiptContent = JSONObject.parseObject(content.getString("receipt"),CalOrderReceiptContent.class);
            logger.info(orderCode + "-receiptOrder-" + JSON.toJSONString(receiptContent));
        }

        if (returnOrder == null) {
            throw new BusinessException(ReturnCode.REQUEST_FAIL, "请求返仓计算服务失败");
        }
        Integer returnType = 2;
        if (receiptContent == null) {
            returnType = 1;
        }

        OrderRoHead insertRoHead = this.returnHeadBuilder(orderHead, oshs, returnOrder, returnHeadDto, returnType, logSign);

        Boolean flag = roOrderService.createRo4Saas(insertRoHead, true, true);

        //通知Es
        if (flag && insertRoHead != null) {

            this.notifyEs(insertRoHead, true, logSign);
        }


//        if (returnHeadDto.getReturnOrderType().equals(OrderRoType.SPOT_RECEIPT.getValue()) && receiptContent != null) {
//            // 保存返仓单
//            this.orderReceiptService.receiptHeadBuider(orderHead, oshs, receiptContent, codeItemMap, logSign);
//
//            // TODO 保存 ??
//        }

        if (insertRoHead != null) {
            res.setCode(ReturnCode.REQUEST_SUCCESS);
            res.setData(insertRoHead);
        } else {
            res.setCode(ReturnCode.REQUEST_FAIL);
        }

        return res;
    }


    protected OrderRoHead returnHeadBuilder(OrderHead orderHead, OrderShippingHeadWithBLOBs oshs, JSONObject returnOrder, ReturnHeadDto returnHeadDto, Integer returnType, String logSign) {
        Long orderCode = orderHead.getOrderCode();
        JSONObject head = returnOrder.getJSONObject("head");
        JSONArray detailList = returnOrder.getJSONArray("detail");

        if (head == null || head.isEmpty()) {
            logger.info(logSign + ":" + orderCode + "返仓头信息为空");
            return null;
        }

        if (detailList == null || detailList.isEmpty()) {
            logger.info(logSign + ":" + orderCode + "返仓列表信息为空");
            return null;
        }

        JSONObject extJson = JSON.parseObject(orderHead.getExt());
        String orderDc = extJson.getString("orderDc");

        logger.info(orderCode + "-head " + head.toJSONString());
        logger.info(orderCode + "-detailList " + detailList.toJSONString());

        OrderRoHead orderRoHead = this.createOrderRoHead(oshs, orderHead, head, returnType);
        orderRoHead.setReturnOrderType(returnHeadDto.getReturnOrderType());
        if (returnHeadDto.getConfirmFlag() == 1) {
            //需要确认的返仓
            orderRoHead.setStatus(ReturnStatus.Waiting_Confirm_So.getIndex());
        }
        OrderShippingHead shippingOrder = shippingService.selectOneByOrderCode(orderHead.getOrderCode(), false);
        if (shippingOrder == null) {
            throw new BusinessException(ReturnCode.FIND_ORDER_IS_NULL, "用户订单号未查询到发货单");
        }

        String asfId = returnHeadDto.getAsfId();
        if (StringUtils.isNotBlank(asfId)) {
            JSONObject extJsonObject = JSON.parseObject(orderRoHead.getExt());
            extJsonObject.put("asf_id", asfId);
            extJsonObject.put("supplier_group_id",orderHead.getSupplierGroupId());
            orderRoHead.setExt(extJsonObject.toJSONString());
        }

        List<OrderRoDetail> orderRoDetailList = this.createOrderRoDetails(oshs, detailList);

        if (orderRoHead == null) {
            logger.info(logSign + ":" + orderCode + ": orderRoHead is null");
            return null;
        }

        if (orderRoDetailList == null || orderRoDetailList.isEmpty()) {
            logger.info(logSign + ":" + orderCode + ": orderRoDetailList is null ");
            return null;
        }

        orderRoHead.setDetails(orderRoDetailList);

//        OrderRoHead insertOrderRoHead = roOrderService.createRo4Pms(orderRoHead, orderRoDetailList, true, true);
//
//        //通知Es
//        if (insertOrderRoHead != null) {
//
//            this.notifyEs(insertOrderRoHead, true, logSign);
//        }

        return orderRoHead;
    }


    /**
     * 组织反仓单头信息 (全单)
     *
     * @param orderShippingHeadWithBLOBs 发货单头信息
     * @return 反仓单头信息
     */
    private OrderRoHead createOrderRoHead(final OrderShippingHeadWithBLOBs orderShippingHeadWithBLOBs, final OrderHead orderHead) {

        int ts = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
        OrderRoHead orderRoHead = new OrderRoHead();

        // 来自订单
        orderRoHead.setOrderId(orderHead.getOrderCode());
        orderRoHead.setUid(orderHead.getUserCode());
        orderRoHead.setAddressId(orderHead.getAddressCode());
        orderRoHead.setProvince(orderHead.getProvince() + "");
        orderRoHead.setCity(orderHead.getCity() + "");
        orderRoHead.setCounty(orderHead.getDistrict() + "");
        orderRoHead.setArea(orderHead.getArea() + "");

        // 来自发货单
        orderRoHead.setShippingOrderId(orderShippingHeadWithBLOBs.getShippingOrderId());
        orderRoHead.setUid(orderShippingHeadWithBLOBs.getUid());
        orderRoHead.setAddressId(orderShippingHeadWithBLOBs.getAddressId());
        orderRoHead.setProvince(orderShippingHeadWithBLOBs.getProvince());
        orderRoHead.setCity(orderShippingHeadWithBLOBs.getCity());
        orderRoHead.setCounty(orderShippingHeadWithBLOBs.getCounty());
        orderRoHead.setArea(orderShippingHeadWithBLOBs.getArea());
        orderRoHead.setWarehouseId(orderShippingHeadWithBLOBs.getWarehouseId());
        orderRoHead.setWarehouseName(orderShippingHeadWithBLOBs.getWarehouseName());
        orderRoHead.setOrderId(orderShippingHeadWithBLOBs.getOrderId());
        orderRoHead.setShippingOrderId(orderShippingHeadWithBLOBs.getShippingOrderId());
        orderRoHead.setSkuCount(orderShippingHeadWithBLOBs.getSkuCount());
        orderRoHead.setRealSkuCount(orderShippingHeadWithBLOBs.getRealSkuCount());
        orderRoHead.setZoneId(orderShippingHeadWithBLOBs.getZoneId());
        orderRoHead.setStorageTypeId(orderShippingHeadWithBLOBs.getStorageTypeId());
        orderRoHead.setOrderFrom(orderShippingHeadWithBLOBs.getOrderFrom());
        orderRoHead.setWarehouseId(orderShippingHeadWithBLOBs.getWarehouseId());
        orderRoHead.setWarehouseName(orderShippingHeadWithBLOBs.getWarehouseName());
        JSONObject shippintExtObject = JSONObject.parseObject(orderShippingHeadWithBLOBs.getExt()).getJSONObject("head_info");
        JSONObject returnExtObject = new JSONObject();
        returnExtObject.put("money", shippintExtObject.get("money"));
        returnExtObject.put("sku_count", shippintExtObject.get("sku_count"));
        returnExtObject.put("real_sku_count", shippintExtObject.get("real_sku_count"));
        JSONObject extObject = new JSONObject();
        extObject.put("head_info", returnExtObject);
        extObject.put("supplier_group_id",orderHead.getSupplierGroupId());
        orderRoHead.setExt(extObject.toJSONString());

        // 系统默认
        orderRoHead.setActivedAt(ts);
        orderRoHead.setReturnAt(ts);
        orderRoHead.setCreatedAt(ts);
        orderRoHead.setUpdatedAt(ts);
        //返仓单标记通过时间(数据组专用)
        orderRoHead.setPassAt(ts);
        //有效
        orderRoHead.setIsValid(Valid.ENABLE.getValue());
        //和寄售一样设置为零
        orderRoHead.setCostMoney(BigDecimal.ZERO);
        //和寄售一样设置为零
        orderRoHead.setCostNtMoney(BigDecimal.ZERO);
        //初始化
        orderRoHead.setStatus(ReturnStatus.Waiting_Submit_So.getIndex());
        orderRoHead.setIsMp(YN.Y.getValue());
        //返仓SO单号
        orderRoHead.setSoReturnId("");
        orderRoHead.setFOrderId(0L);
        //1-正常返仓,2-异常返仓
        orderRoHead.setType(1);
        //返仓类型：1-全部返仓；2-部分返仓
        orderRoHead.setReturnType(1);
        //1-正常；2-包含寄售
        orderRoHead.setItemType(1);
        //全单返仓备注
        orderRoHead.setReturnNote(0);
        //返仓单类型：1-现场返仓；2-售后返仓
//        orderRoHead.setReturnOrderType(1);
        orderRoHead.setTmsId(0L);
        logger.info("pms 全单返仓对象商城");

        return orderRoHead;
    }


    /**
     * 组织反仓单头信息
     *
     * @param orderShippingHeadWithBLOBs 发货单头信息
     * @return 反仓单头信息
     */
    private OrderRoHead createOrderRoHead(final OrderShippingHeadWithBLOBs orderShippingHeadWithBLOBs, final OrderHead orderHead, JSONObject head, Integer returnType) {

        int ts = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
        OrderRoHead orderRoHead = new OrderRoHead();
        // 来自订单
        orderRoHead.setOrderId(orderHead.getOrderCode());
        orderRoHead.setUid(orderHead.getUserCode());
        orderRoHead.setAddressId(orderHead.getAddressCode());
        orderRoHead.setProvince(orderHead.getProvince() + "");
        orderRoHead.setCity(orderHead.getCity() + "");
        orderRoHead.setCounty(orderHead.getDistrict() + "");
        orderRoHead.setArea(orderHead.getArea() + "");

        // 来自发货
        orderRoHead.setShippingOrderId(orderShippingHeadWithBLOBs.getShippingOrderId());
        orderRoHead.setUid(orderShippingHeadWithBLOBs.getUid());
        orderRoHead.setAddressId(orderShippingHeadWithBLOBs.getAddressId());
        orderRoHead.setProvince(orderShippingHeadWithBLOBs.getProvince());
        orderRoHead.setCity(orderShippingHeadWithBLOBs.getCity());
        orderRoHead.setCounty(orderShippingHeadWithBLOBs.getCounty());
        orderRoHead.setArea(orderShippingHeadWithBLOBs.getArea());
        orderRoHead.setWarehouseId(orderShippingHeadWithBLOBs.getWarehouseId());
        orderRoHead.setWarehouseName(orderShippingHeadWithBLOBs.getWarehouseName());
        orderRoHead.setOrderId(orderShippingHeadWithBLOBs.getOrderId());
        orderRoHead.setShippingOrderId(orderShippingHeadWithBLOBs.getShippingOrderId());
        orderRoHead.setZoneId(orderShippingHeadWithBLOBs.getZoneId());
        orderRoHead.setStorageTypeId(orderShippingHeadWithBLOBs.getStorageTypeId());
        orderRoHead.setOrderFrom(orderShippingHeadWithBLOBs.getOrderFrom());
        orderRoHead.setWarehouseId(orderShippingHeadWithBLOBs.getWarehouseId());
        orderRoHead.setWarehouseName(orderShippingHeadWithBLOBs.getWarehouseName());

        // 来自计算服务
        orderRoHead.setSkuCount(head.getBigDecimal("sku_count"));
        orderRoHead.setRealSkuCount(head.getBigDecimal("real_sku_count"));
        JSONObject jsonObject = JSON.parseObject(head.getString("ext"));
        jsonObject.put("supplier_group_id", orderHead.getSupplierGroupId());
        orderRoHead.setExt(jsonObject.toJSONString());
        orderRoHead.setMoney(head.getBigDecimal("money"));
        //和寄售一样设置为零
        orderRoHead.setCostMoney(BigDecimal.ZERO);
        //和寄售一样设置为零
        orderRoHead.setCostNtMoney(BigDecimal.ZERO);
        //返仓单类型：1-现场返仓；2-售后返仓
//        orderRoHead.setReturnOrderType(1);
        //返仓类型：1-全部返仓；2-部分返仓
        orderRoHead.setReturnType(returnType);
        //返仓SO单号
        orderRoHead.setSoReturnId("");

        // 默认值
        orderRoHead.setFOrderId(0L);
        //1-正常返仓,2-异常返仓
        orderRoHead.setType(1);
        orderRoHead.setIsMp(YN.Y.getValue());
        //初始化
        orderRoHead.setStatus(ReturnStatus.Waiting_Submit_So.getIndex());
        //有效
        orderRoHead.setIsValid(Valid.ENABLE.getValue());
        orderRoHead.setActivedAt(ts);
        orderRoHead.setReturnAt(ts);
        orderRoHead.setCreatedAt(ts);
        orderRoHead.setUpdatedAt(ts);
        //返仓单标记通过时间(数据组专用)
        orderRoHead.setPassAt(ts);
        //1-正常；2-包含寄售
        orderRoHead.setItemType(1);
        //全单返仓备注
        orderRoHead.setReturnNote(0);
        orderRoHead.setTmsId(0L);

        return orderRoHead;
    }


    private List<OrderRoDetail> createOrderRoDetails(final OrderShippingHeadWithBLOBs osh, JSONArray detailList) {

        List<OrderShippingDetail> orderShippingDetailList = shippingService.getDetails(osh.getShippingOrderId());

        List<OrderRoDetail> orderRoDetailList = new ArrayList<>(orderShippingDetailList.size());
        int ts = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());

        Map<String, OrderShippingDetail> code2ShipDetailMap = new HashMap<>();
        for (OrderShippingDetail orderShippingDetail : orderShippingDetailList) {
            code2ShipDetailMap.put(orderShippingDetail.getCode(), orderShippingDetail);
        }

        OrderRoDetail orderRoDetail;
        JSONObject returnDetail;
        JSONObject ext;
        OrderShippingDetail orderShippingDetail;
        for (Object detail : detailList) {
            if (detail == null) {
                logger.info("反仓单信息详情为空");
                continue;
            }

            returnDetail = JSONObject.parseObject(detail.toString());
            ext = returnDetail.getJSONObject("ext");
            String wmCode = ext.getString("wm_code");

            orderShippingDetail = code2ShipDetailMap.get(wmCode);

            orderRoDetail = new OrderRoDetail();

            orderRoDetail.setItemId(orderShippingDetail.getItemId());
            orderRoDetail.setSupplierOrg(orderShippingDetail.getSupplierOrg());
            orderRoDetail.setZoneId(orderShippingDetail.getZoneId());
            orderRoDetail.setStatus(orderShippingDetail.getStatus());

            orderRoDetail.setSkuId(returnDetail.getLong("sku_id"));
            orderRoDetail.setSkuName(returnDetail.getString("sku_name"));
            orderRoDetail.setSaleUnit(returnDetail.getBigDecimal("sale_unit"));
            orderRoDetail.setQty(returnDetail.getBigDecimal("qty"));
            orderRoDetail.setRealQty(returnDetail.getBigDecimal("real_qty"));
            orderRoDetail.setExt(returnDetail.getString("ext"));
            orderRoDetail.setPrice(returnDetail.getBigDecimal("price"));
            orderRoDetail.setMoney(returnDetail.getBigDecimal("money"));
            orderRoDetail.setCreatedAt(ts);
            orderRoDetail.setUpdatedAt(ts);
            //商品返仓备注
            orderRoDetail.setReturnNote(0);
            //补偿原因
            orderRoDetail.setMakeUpNote("");
            orderRoDetail.setTmsId(0L);
            // TODO 2019-07-30
            orderRoDetail.setItemCode(returnDetail.getInteger("item_code"));

            orderRoDetailList.add(orderRoDetail);
        }

        return orderRoDetailList;
    }

    /**
     * 组织反仓单详细信息 (全单)
     *
     * @param orderRoHead 反仓单金额
     * @param osh         发货单头信息
     * @return 反仓单详细信息
     */
    private List<OrderRoDetail> createOrderRoDetails(final OrderShippingHeadWithBLOBs osh, OrderRoHead orderRoHead) {

        List<OrderShippingDetail> orderShippingDetailList = shippingService.getDetails(osh.getShippingOrderId());
        List<OrderRoDetail> orderRoDetailList = new ArrayList<>(orderShippingDetailList.size());
        int ts = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
        BigDecimal money = BigDecimal.ZERO;
        BigDecimal totalQty = BigDecimal.ZERO;
        BigDecimal totalRealQty = BigDecimal.ZERO;
        for (OrderShippingDetail orderShippingDetail : orderShippingDetailList) {
            OrderRoDetail orderRoDetail = new OrderRoDetail();
            orderRoDetail.setSkuId(orderShippingDetail.getSkuId());
            orderRoDetail.setSkuName(orderShippingDetail.getSkuName());
            orderRoDetail.setItemId(orderShippingDetail.getItemId());
            orderRoDetail.setSaleUnit(orderShippingDetail.getSaleUnit());
            orderRoDetail.setQty(orderShippingDetail.getQty());
            orderRoDetail.setRealQty(orderShippingDetail.getRealQty());
            orderRoDetail.setStatus(orderShippingDetail.getStatus());
            orderRoDetail.setExt(orderShippingDetail.getExt());
            orderRoDetail.setSupplierOrg(orderShippingDetail.getSupplierOrg());
            orderRoDetail.setZoneId(orderShippingDetail.getZoneId());
            orderRoDetail.setPrice(orderShippingDetail.getPrice());
            orderRoDetail.setMoney(orderShippingDetail.getMoney());
            orderRoDetail.setCreatedAt(ts);
            orderRoDetail.setUpdatedAt(ts);
            orderRoDetail.setReturnNote(0);
            orderRoDetail.setMakeUpNote("");
            orderRoDetail.setTmsId(0L);
            // TODO 2019-07-10
            orderRoDetail.setItemCode(orderShippingDetail.getItemCode());

            orderRoDetailList.add(orderRoDetail);
            money = money.add(orderRoDetail.getQty().multiply(orderRoDetail.getPrice()));
            totalQty = totalQty.add(orderShippingDetail.getQty());
            totalRealQty = totalRealQty.add(orderShippingDetail.getRealQty());
        }

        orderRoHead.setMoney(money);
        orderRoHead.setSkuCount(totalQty);
        orderRoHead.setRealSkuCount(totalRealQty);

        return orderRoDetailList;
    }


    private void notifyEs(final OrderRoHead orderRoHead) {

        try {

            logger.info("ES返仓新建入参是 -- " + JsonUtils.obj2Json(orderRoHead));
            esProxy.createIndex(orderRoHead, orderRoHead.getReturnOrderId() + "");
        } catch (Exception e) {
            logger.info("订单号" + orderRoHead.getReturnOrderId() + ",生成发货单同步es失败。");
            logger.info(e.getMessage(), e);
        }
    }


    /**
     * 通知es
     *
     * @param orderRoHead 订单号
     * @param logSign     唯一标识
     */
    private void notifyEs(final OrderRoHead orderRoHead, boolean allFlag, final String logSign) {

        Long orderCode = orderRoHead.getOrderId();

        try {
            logger.info(logSign + "ES返仓新建入参是 -- " + JsonUtils.obj2Json(orderRoHead));
            esProxy.createIndex(orderRoHead, logSign);
            if (allFlag) {
                OrderShippingHeadWithBLOBs oshEs = new OrderShippingHeadWithBLOBs();
                oshEs.setShippingOrderId(orderRoHead.getShippingOrderId());
                oshEs.setOrderId(orderCode);
                oshEs.setStatus(ShippingStatus.DELIVERED.getIndex());
                logger.info(logSign + "ES返仓更新发货单入参是 -- " + JsonUtils.obj2Json(oshEs));
                esProxy.editIndex(oshEs, logSign);

                OrderHeadForEs ohEs = new OrderHeadForEs();
                ohEs.setOrderCode(orderCode);
                ohEs.setOrderStatus(OrderStatus.ORDER_SIGN.getIndex());
                logger.info(logSign + "ES返仓更新订单入参是 -- " + JsonUtils.obj2Json(ohEs));
                esProxy.editIndex(ohEs, logSign);
            }
        } catch (Exception e) {
            logger.info(logSign + "订单号" + orderCode + ",生成发货单同步es失败。");
            logger.info(e.getMessage(), e);
        }
    }
}
